package com.lehecai.core.thread;


import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 通过给定的runnable模板复制出多个执行对象并启动多线程执行
 * 注意: 要复制的对象的属性必须有完整的getter/setter
 * @author Sunshow
 *
 */
public class MultiThreadContainer {

    protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());

    private int threadCount = 1;

	private IThreadRunnable runnableTemplate;
	private String name;

    private long beforeRunWaitTime;

    private List<ThreadContainer> threadContainerList;

	public MultiThreadContainer(IThreadRunnable runnable) {
		this(runnable, null);
	}

	public MultiThreadContainer(IThreadRunnable runnable, String name) {
		this.runnableTemplate = runnable;
		this.name = name;
	}

	public void start() {
        if (this.threadCount < 1) {
            this.threadCount = 1;
        }
        threadContainerList = new ArrayList<ThreadContainer>();
        for (int i = 0; i < this.threadCount; i++) {
            try {
                IThreadRunnable runnable = (IThreadRunnable)BeanUtils.cloneBean(this.runnableTemplate);
                String name = this.name;
                if (name != null) {
                    name = String.format("%s(子线程:%s)", name, i);
                }
                ThreadContainer container = new ThreadContainer(runnable, name);
                container.setBeforeRunWaitTime(this.beforeRunWaitTime);
                container.start();

                threadContainerList.add(container);
            } catch (Exception e) {
                logger.error("为多线程创建运行类失败", e);
            }
        }
	}
	
	public void stop() {
        if (threadContainerList != null) {
            for (ThreadContainer threadContainer : threadContainerList) {
                threadContainer.stop();
            }
        }
	}
	
	public void executeNotify() {
        if (threadContainerList != null) {
            for (ThreadContainer threadContainer : threadContainerList) {
                threadContainer.executeNotify();
            }
        }
	}

    public void setThreadCount(int threadCount) {
        this.threadCount = threadCount;
    }

    public void setBeforeRunWaitTime(long beforeRunWaitTime) {
        this.beforeRunWaitTime = beforeRunWaitTime;
    }
}
